using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;

namespace Catastrophe.AutoSulution.TaskM
{
	public abstract class BaseTask
	{
		/// <summary>
		/// 任务管理
		/// </summary>
		public readonly Dictionary<string, MyTask> DicTask = new Dictionary<string, MyTask>();

		/// <summary>
		/// 命名空间用来确定唯一name
		/// </summary>
		public string NameSpace { get; set; }

		/// <summary>
		/// 任务信息格式化
		/// </summary>
		/// <param name="methodName"></param>
		/// <returns></returns>
		public string TaskFormat(string methodName)
		{
			if (this.DicTask.ContainsKey(methodName))
			{
				DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(18, 5);
				defaultInterpolatedStringHandler.AppendLiteral("方法名称:");
				defaultInterpolatedStringHandler.AppendFormatted(this.DicTask[methodName].MethodName);
				defaultInterpolatedStringHandler.AppendFormatted(Environment.NewLine);
				defaultInterpolatedStringHandler.AppendLiteral("功能描述:");
				defaultInterpolatedStringHandler.AppendFormatted(this.DicTask[methodName].Function);
				defaultInterpolatedStringHandler.AppendLiteral("开始时间:");
				defaultInterpolatedStringHandler.AppendFormatted(this.DicTask[methodName].StartTime);
				defaultInterpolatedStringHandler.AppendLiteral("异常:");
				defaultInterpolatedStringHandler.AppendFormatted(this.DicTask[methodName].Exception);
				return defaultInterpolatedStringHandler.ToStringAndClear();
			}
			return "不存在的任务";
		}

		/// <summary>
		/// 任务信息格式化
		/// </summary>
		/// <param name="act"></param>
		/// <returns></returns>
		public string TaskFormat(Action act)
		{
			return this.TaskFormat(this.GetName(act));
		}

		/// <summary>
		/// 通知线程暂停
		/// </summary>
		/// <param name="methodName">方法</param>
		/// <param name="pause">是否暂停</param>
		/// <returns></returns>
		public bool ManualReset(string methodName, bool pause = true)
		{
			if (this.DicTask.ContainsKey(methodName))
			{
				if (!pause)
				{
					this.DicTask[methodName].ManualReset.Set();
				}
				else
				{
					this.DicTask[methodName].ManualReset.Reset();
				}
				return true;
			}
			return false;
		}

		public bool ManualReset(Action act, bool pause = true)
		{
			return this.ManualReset(this.GetName(act), pause);
		}

		/// <summary>
		/// taskName格式化
		/// </summary>
		/// <param name="act"></param>
		/// <returns></returns>
		public string GetName(Action act)
		{
			MethodInfo method = act.Method;
			return string.IsNullOrEmpty(this.NameSpace) ? method.Name : (this.NameSpace + method.Name);
		}

		/// <summary>
		/// 任务衔接
		/// </summary>
		/// <param name="mothodName">集合方法名称</param>
		/// <param name="destAction">目标委托</param>
		/// <returns></returns>
		public bool Continue(string mothodName, Action<Task> destAction)
		{
			if (this.DicTask.ContainsKey(mothodName))
			{
				this.DicTask[mothodName].TaskNow.ContinueWith(destAction);
				return true;
			}
			return false;
		}

		/// <summary>
		/// 任务连接
		/// </summary>
		/// <param name="act">原委托</param>
		/// <param name="destAction">目标委托</param>
		/// <returns></returns>
		public bool Continue(Action act, Action<Task> destAction)
		{
			return this.Continue(this.GetName(act), destAction);
		}

		/// <summary>
		/// 默认DicTask最后一个任务后衔接
		/// </summary>
		/// <param name="destAction">目标委托</param>
		/// <returns></returns>
		public bool Continue(Action<Task> destAction)
		{
			if (this.DicTask.Count == 0)
			{
				return false;
			}
			return this.Continue(this.DicTask.Keys.LastOrDefault(), destAction);
		}

		/// <summary>
		/// 任务状态
		/// </summary>
		/// <param name="name">方法名称</param>
		/// <returns></returns>
		public TaskStatus TaskState(string name)
		{
			TaskStatus result = TaskStatus.Created;
			if (this.DicTask.ContainsKey(name))
			{
				result = this.DicTask[name].TaskNow.Status;
			}
			return result;
		}

		public TaskStatus TaskState(Action act)
		{
			return this.TaskState(this.GetName(act));
		}

		/// <summary>
		/// 不同任务设定时间
		/// </summary>
		/// <param name="name">方法</param>
		/// <param name="time">时间戳</param>
		public void SetStartTime(string name, DateTime time)
		{
			if (this.DicTask.ContainsKey(name))
			{
				this.DicTask[name].StartTime = time;
			}
		}

		public void SetStartTime(Action act, DateTime time)
		{
			this.SetStartTime(this.GetName(act), time);
		}

		/// <summary>
		/// 任务开始时间
		/// </summary>
		/// <param name="name">方法</param>
		/// <returns></returns>
		public DateTime? GetStartTime(string name)
		{
			if (this.DicTask.ContainsKey(name))
			{
				return this.DicTask[name].StartTime;
			}
			return null;
		}

		/// <summary>
		/// 任务开始时间
		/// </summary>
		/// <param name="act">方法</param>
		/// <returns></returns>
		public DateTime? GetStartTime(Action act)
		{
			return this.GetStartTime(this.GetName(act));
		}

		/// <summary>
		/// 重新启动任务
		/// </summary>
		/// <param name="mothodName"></param>
		/// <returns></returns>
		public bool ResumeTask(string mothodName)
		{
			if (this.DicTask.ContainsKey(mothodName) && this.TaskState(mothodName) == TaskStatus.RanToCompletion)
			{
				this.DicTask[mothodName].TaskNow.Start();
				return true;
			}
			return false;
		}

		/// <summary>
		/// 重启任务
		/// </summary>
		/// <param name="act"></param>
		/// <returns></returns>
		public bool ResumeTask(Action act)
		{
			return this.ResumeTask(this.GetName(act));
		}

		/// <summary>
		/// 取消任务
		/// </summary>
		/// <param name="mothodName"></param>
		/// <param name="actCallBack"></param>
		/// <returns></returns>
		public bool CancelTask(string mothodName, Action actCallBack = null)
		{
			if (this.DicTask.ContainsKey(mothodName))
			{
				if (actCallBack != null)
				{
					this.DicTask[mothodName].TokenSource.Token.Register(actCallBack);
				}
				this.DicTask[mothodName].TokenSource.Cancel();
			}
			return false;
		}

		/// <summary>
		/// 取消任务
		/// </summary>
		/// <param name="act">方法</param>
		/// <param name="actCallBack">回调</param>
		/// <returns></returns>
		public bool CancelTask(Action act, Action actCallBack = null)
		{
			return this.CancelTask(this.GetName(act), actCallBack);
		}

		/// <summary>
		/// 移除任务
		/// </summary>
		/// <param name="methodName">方法</param>
		public void RemoveTaskSingle(string methodName)
		{
			if (this.DicTask.ContainsKey(methodName))
			{
				this.DicTask.Remove(methodName);
			}
		}

		/// <summary>
		/// 移除任务
		/// </summary>
		/// <param name="act"></param>
		public void RemoveTaskSingle(Action act)
		{
			this.RemoveTaskSingle(this.GetName(act));
		}

		/// <summary>
		/// 移除所有任务
		/// </summary>
		public void RemoveTaskAll()
		{
			this.DicTask.Clear();
		}

		/// <summary>
		/// 记录时间开始
		/// </summary>
		/// <param name="isRecord"></param>
		/// <returns></returns>
		protected Stopwatch BeginRecord(bool isRecord)
		{
			Stopwatch stopwatch = null;
			if (isRecord)
			{
				stopwatch = new Stopwatch();
				stopwatch.Start();
			}
			return stopwatch;
		}

		/// <summary>
		/// 记录时间结束
		/// </summary>
		/// <param name="wt"></param>
		/// <param name="myTask"></param>
		/// <param name="recordPoint"></param>
		protected void EndRecord(Stopwatch wt, MyTask myTask, int recordPoint)
		{
			if (wt != null)
			{
				wt.Stop();
				myTask.CycleValueNow = wt.ElapsedMilliseconds;
				myTask.RecordCycleBuffer.Enqueue(wt.ElapsedMilliseconds);
				if (myTask.RecordCycleBuffer.Count > recordPoint)
				{
					myTask.RecordCycleBuffer.Dequeue();
				}
			}
		}
	}
}
